From e6649dfa6d237609b30f283494dd95739732291f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 2 Jun 2017 09:31:44 -0700 Subject: [PATCH] Cache `Context::target_filenames` Relatively expensive to calculate, never changes, easy to add a cache! --- src/cargo/ops/cargo_clean.rs | 8 ++-- src/cargo/ops/cargo_rustc/context.rs | 13 +++++- src/cargo/ops/cargo_rustc/fingerprint.rs | 4 +- src/cargo/ops/cargo_rustc/mod.rs | 49 ++++++++++++--------- src/cargo/ops/cargo_rustc/output_depinfo.rs | 4 +- 5 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 8a15bf196..19f518f80 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -83,10 +83,10 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> { continue } - for (src, link_dst, _) in cx.target_filenames(unit)? { - rm_rf(&src)?; - if let Some(dst) = link_dst { - rm_rf(&dst)?; + for &(ref src, ref link_dst, _) in cx.target_filenames(unit)?.iter() { + rm_rf(src)?; + if let Some(ref dst) = *link_dst { + rm_rf(dst)?; } } } diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 9842306bd..1b1242f90 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -53,6 +53,7 @@ pub struct Context<'a, 'cfg: 'a> { host_info: TargetInfo, profiles: &'a Profiles, incremental_enabled: bool, + target_filenames: HashMap, Arc, bool)>>>, } #[derive(Clone, Default)] @@ -133,6 +134,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { used_in_plugin: HashSet::new(), incremental_enabled: incremental_enabled, jobserver: jobserver, + target_filenames: HashMap::new(), }) } @@ -544,8 +546,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// filename: filename rustc compiles to. (Often has metadata suffix). /// link_dst: Optional file to link/copy the result to (without metadata suffix) /// linkable: Whether possible to link against file (eg it's a library) - pub fn target_filenames(&mut self, unit: &Unit) - -> CargoResult, bool)>> { + pub fn target_filenames(&mut self, unit: &Unit<'a>) + -> CargoResult, bool)>>> { + if let Some(cache) = self.target_filenames.get(unit) { + return Ok(cache.clone()) + } + let out_dir = self.out_dir(unit); let stem = self.file_stem(unit); let link_stem = self.link_stem(unit); @@ -621,6 +627,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> { unit.pkg, self.target_triple()); } info!("Target filenames: {:?}", ret); + + let ret = Arc::new(ret); + self.target_filenames.insert(*unit, ret.clone()); Ok(ret) } diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index 816bbe154..a3fc7ffe5 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -85,9 +85,9 @@ pub fn prepare_target<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, missing_outputs = !root.join(unit.target.crate_name()) .join("index.html").exists(); } else { - for (src, link_dst, _) in cx.target_filenames(unit)? { + for &(ref src, ref link_dst, _) in cx.target_filenames(unit)?.iter() { missing_outputs |= !src.exists(); - if let Some(link_dst) = link_dst { + if let Some(ref link_dst) = *link_dst { missing_outputs |= !link_dst.exists(); } } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 58e069a13..e77740763 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -142,23 +142,23 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>, queue.execute(&mut cx)?; for unit in units.iter() { - for (dst, link_dst, _linkable) in cx.target_filenames(unit)? { - let bindst = match link_dst { - Some(link_dst) => link_dst, - None => dst.clone(), + for &(ref dst, ref link_dst, _) in cx.target_filenames(unit)?.iter() { + let bindst = match *link_dst { + Some(ref link_dst) => link_dst, + None => dst, }; if unit.profile.test { cx.compilation.tests.push((unit.pkg.clone(), unit.target.kind().clone(), unit.target.name().to_string(), - dst)); + dst.clone())); } else if unit.target.is_bin() || unit.target.is_example() { - cx.compilation.binaries.push(bindst); + cx.compilation.binaries.push(bindst.clone()); } else if unit.target.is_lib() { let pkgid = unit.pkg.package_id().clone(); cx.compilation.libraries.entry(pkgid).or_insert(HashSet::new()) - .insert((unit.target.clone(), dst)); + .insert((unit.target.clone(), dst.clone())); } } @@ -179,8 +179,8 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>, cx.compilation.libraries .entry(unit.pkg.package_id().clone()) .or_insert(HashSet::new()) - .extend(v.into_iter().map(|(f, _, _)| { - (dep.target.clone(), f) + .extend(v.iter().map(|&(ref f, _, _)| { + (dep.target.clone(), f.clone()) })); } @@ -252,7 +252,9 @@ fn compile<'a, 'cfg: 'a>(cx: &mut Context<'a, 'cfg>, Ok(()) } -fn rustc(cx: &mut Context, unit: &Unit, exec: Arc) -> CargoResult { +fn rustc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, + unit: &Unit<'a>, + exec: Arc) -> CargoResult { let crate_types = unit.target.rustc_crate_types(); let mut rustc = prepare_rustc(cx, crate_types, unit)?; @@ -449,7 +451,9 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc) -> CargoResult CargoResult { +fn link_targets<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, + unit: &Unit<'a>, + fresh: bool) -> CargoResult { let filenames = cx.target_filenames(unit)?; let package_id = unit.pkg.package_id().clone(); let target = unit.target.clone(); @@ -572,9 +576,9 @@ fn filter_dynamic_search_path<'a, I>(paths :I, root_output: &PathBuf) -> Vec, - unit: &Unit) -> CargoResult { +fn prepare_rustc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, + crate_types: Vec<&str>, + unit: &Unit<'a>) -> CargoResult { let mut base = cx.compilation.rustc_process(unit.pkg)?; base.inherit_jobserver(&cx.jobserver); build_base_args(cx, &mut base, unit, &crate_types); @@ -583,7 +587,8 @@ fn prepare_rustc(cx: &mut Context, } -fn rustdoc(cx: &mut Context, unit: &Unit) -> CargoResult { +fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, + unit: &Unit<'a>) -> CargoResult { let mut rustdoc = cx.compilation.rustdoc_process(unit.pkg)?; rustdoc.inherit_jobserver(&cx.jobserver); rustdoc.arg("--crate-name").arg(&unit.target.crate_name()) @@ -813,8 +818,9 @@ fn build_base_args(cx: &mut Context, } -fn build_deps_args(cmd: &mut ProcessBuilder, cx: &mut Context, unit: &Unit) - -> CargoResult<()> { +fn build_deps_args<'a, 'cfg>(cmd: &mut ProcessBuilder, + cx: &mut Context<'a, 'cfg>, + unit: &Unit<'a>) -> CargoResult<()> { cmd.arg("-L").arg(&{ let mut deps = OsString::from("dependency="); deps.push(cx.deps_dir(unit)); @@ -842,10 +848,11 @@ fn build_deps_args(cmd: &mut ProcessBuilder, cx: &mut Context, unit: &Unit) return Ok(()); - fn link_to(cmd: &mut ProcessBuilder, cx: &mut Context, unit: &Unit) - -> CargoResult<()> { - for (dst, _link_dst, linkable) in cx.target_filenames(unit)? { - if !linkable { + fn link_to<'a, 'cfg>(cmd: &mut ProcessBuilder, + cx: &mut Context<'a, 'cfg>, + unit: &Unit<'a>) -> CargoResult<()> { + for &(ref dst, _, ref linkable) in cx.target_filenames(unit)?.iter() { + if !*linkable { continue } let mut v = OsString::new(); diff --git a/src/cargo/ops/cargo_rustc/output_depinfo.rs b/src/cargo/ops/cargo_rustc/output_depinfo.rs index a7f67a043..60adf939e 100644 --- a/src/cargo/ops/cargo_rustc/output_depinfo.rs +++ b/src/cargo/ops/cargo_rustc/output_depinfo.rs @@ -61,8 +61,8 @@ pub fn output_depinfo<'a, 'b>(context: &mut Context<'a, 'b>, unit: &Unit<'a>) -> let mut visited = HashSet::new(); let success = add_deps_for_unit(&mut deps, context, unit, &mut visited).is_ok(); let basedir = None; // TODO - for (_filename, link_dst, _linkable) in context.target_filenames(unit)? { - if let Some(link_dst) = link_dst { + for &(_, ref link_dst, _) in context.target_filenames(unit)?.iter() { + if let Some(ref link_dst) = *link_dst { let output_path = link_dst.with_extension("d"); if success { let mut outfile = BufWriter::new(File::create(output_path)?); -- 2.30.2